package com.xxwy.dependency.injection.resolution;

import com.xxwy.dependency.User;
import com.xxwy.dependency.injection.build.InjectedUser;
import com.xxwy.dependency.injection.build.MyAutowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;

import javax.inject.Inject;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Optional;

import static org.springframework.context.annotation.AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME;

/**
 * 注解驱动：依赖注入处理过程.,先依赖查找。
 *
 * @author xxwy
 * @date 2021/7/5 0005
 */
public class AnnotationDependencyInjectionResolutionDemo {

    /**
     * 实时注入 + 通过User.class类型依赖查找（处理） + [字段名称（user）?在primary后匹配]
     * require = true
     * eager = true
     * class = User.class
     * name = user
     * primary = ture
     */
    @Autowired
    private User user;

    @Autowired
    private Optional<User> optionalUser;

//    @Autowired
//    private User superUser;

    /**
     * 顺序是：定义的顺序
     */
    @Autowired
    private Map<String, User> userMap;

    @Inject
    private User userInject;

    @MyAutowired
    private User userDiy;

    @InjectedUser
    private User userDiy2;

//    /**
//     * Inject 不存在，会出现编译错误
//     * @return
//     */
    @Bean(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)
    public static AutowiredAnnotationBeanPostProcessor beanPostProcessor() {
        AutowiredAnnotationBeanPostProcessor beanPostProcessor = new AutowiredAnnotationBeanPostProcessor();
        LinkedHashSet<Class<? extends Annotation>> setAnnotation = new LinkedHashSet<>(Arrays.asList(Autowired.class, Inject.class, InjectedUser.class));
        beanPostProcessor.setAutowiredAnnotationTypes(setAnnotation);
        System.out.println("AutowiredAnnotationBeanPostProcessor 实例化");
        return beanPostProcessor;
    }

    public AnnotationDependencyInjectionResolutionDemo() {
        System.out.println("AnnotationDependencyInjectionResolutionDemo 实例化");
    }
    //    @Bean
//    @Order(Ordered.LOWEST_PRECEDENCE - 3)
//    public static AutowiredAnnotationBeanPostProcessor beanPostProcessor() {
//        AutowiredAnnotationBeanPostProcessor beanPostProcessor = new AutowiredAnnotationBeanPostProcessor();
//        beanPostProcessor.setAutowiredAnnotationType(InjectedUser.class);
//        return beanPostProcessor;
//    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(AnnotationDependencyInjectionResolutionDemo.class);

        // xml
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(applicationContext);
        xmlBeanDefinitionReader.loadBeanDefinitions("classpath:/META-INF/dependency-lookup-context.xml");

        // 启动spring上下文
        applicationContext.refresh();

        AnnotationDependencyInjectionResolutionDemo bean = applicationContext.getBean(AnnotationDependencyInjectionResolutionDemo.class);

        System.out.println("------------@Autowired--------------");
        System.out.println(bean.user);
        System.out.println("------------Optional--------------");
        System.out.println(bean.optionalUser);
        System.out.println("-----------Map Multiple---------------");
        System.out.println(bean.userMap);
        System.out.println("----------@Inject----------------");
        System.out.println(bean.userInject);

        System.out.println("----------自定义注解----------------");
        System.out.println(bean.userDiy);
        System.out.println(bean.userDiy2);

        applicationContext.close();
    }
}
